import React, { useEffect } from "react";
import FountainCode from './FountainCode';
import FountainDecoder from './FountainDecoder';
import { stringToBinary, binaryToString } from "@/utils/common";

let originalData = "喷泉码是一种强大的前向纠错码技术。它能够在不可靠的网络环境中保证数据的可靠传输，特别适用于广播式通信场景。使用喷泉码，发送方可以生成无限数量的编码包，接收方只需收集足够数量的包即可恢复原始数据，无需知道确切需要多少个包。这一特性使得喷泉码在内容分发网络、无线传感器网络和对等网络等领域有广泛的应用。";
// let originalData = 'Fountain code is a powerful forward error correction code technology. It can ensure reliable transmission of data in unreliable network environments, especially suitable for broadcast communication scenarios. Using fountain codes, the sender can generate an infinite number of encoded packets, and the receiver only needs to collect enough packets to recover the original data without knowing exactly how many packets are needed. This feature makes fountain codes widely used in content distribution networks, wireless sensor networks, and peer-to-peer networks.';
console.log("原始数据:", originalData);

originalData = stringToBinary(originalData);

export default () => {
    useEffect(() => {
        runAdvancedTest(10);
        // testByLossRate();
    }, []);

    // 测试不同丢包率下的解码成功率
    const testByLossRate = async () => {
        const lossRates = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90];
        for (const r of lossRates) {
            let successCount = 0;
            for (let i = 0; i < 100; i++) {
                const result = runAdvancedTest(r);
                if (result) {
                    successCount++;
                }
            }
            console.log(`## 模拟丢包率${r}%，解码成功率${successCount}%`);
        }
    }

    // 优化后的测试用例
    function runAdvancedTest(lossRate: number): boolean {
        const fc = new FountainCode();
        
        const blockSize = 64;
        const k = Math.ceil(originalData.length / blockSize);
        const numEncodedBlocks = Math.floor(k * 2);

        // console.log(`================== 喷泉码测试 开始 模拟丢包率${lossRate}% ==================`);

        // 编码（发送端）
        const encodedBlocks = fc.encode(
            originalData,
            blockSize,
            numEncodedBlocks
        );

        // 创建解码器（接收端只需要这个）
        const decoder = new FountainDecoder(
            k,
            blockSize,
            originalData.length
        );
        let packetsSent = 0;
        let packetsReceived = 0;
        let fullyDecoded = false;

        // 模拟发送编码包（网络传输）
        for (const block of encodedBlocks) {
            packetsSent++;

            if (Math.random() * 100 >= lossRate) {
                packetsReceived++;

                // 接收并处理编码包（接收端逻辑）
                decoder.receivePacket(block);

                // 检查是否已完全解码
                if (!fullyDecoded && decoder.isFullyDecoded()) {
                    fullyDecoded = true;

                    // 验证解码结果（接收端逻辑）
                    try {
                        const decodedData = decoder.getDecodedData();
                        const decodedString = new TextDecoder().decode(
                            decodedData
                        );
                        console.log("full 解码数据:", binaryToString(decodedString));
                        // console.log(`full 解码${decodedString === originalData ? `成功, 发送: ${packetsSent}, 接收: ${packetsReceived} (${(
                        //     (packetsReceived / k) *
                        //     100
                        // ).toFixed(1)}% of k)` : '失败'}`);
                    } catch (error: any) {
                        // console.log("full 解码失败:", error.message);
                    }
                    break;
                }

                // 如果尚未完全解码，尝试高斯消元法
                if (!fullyDecoded && packetsReceived >= k) {
                    const success = decoder.tryGaussianElimination();
                    if (success) {
                        fullyDecoded = true;

                        // 验证解码结果
                        try {
                            const decodedData = decoder.getDecodedData();
                            const decodedString = new TextDecoder().decode(
                                decodedData
                            );
                            console.log("GS 解码数据:", binaryToString(decodedString));
                            // console.log(`GS 解码${decodedString === originalData ? '成功' : '失败'}`);
                        } catch (error: any) {
                            // console.log("GS 解码失败:", error.message);
                        }
                        break;
                    }
                }
            }
        }

        // // if (!fullyDecoded) {
        // //     console.log(`解码失败! 发送: ${packetsSent}, 接收: ${packetsReceived}`);
        // // }
        // // console.log("================== 喷泉码测试 结束 ==================");
        return fullyDecoded;
    }

    return <div>喷泉码</div>;
};
